Дерево поиска

A. Простое двоичное дерево поиска

Ограничение по времени на тест: 2 секунды
Ограничение по памяти на тест: 512 мегабайт

Реализуйте просто двоичное дерево поиска.

Входные данные

Входной файл содержит описание операций с деревом, их количество не превышает 100. В каждой строке находится одна из следующих операций:

  • insert xx — добавить в дерево ключ xx. Если ключ xx есть в дереве, то ничего делать не надо;
  • delete xx — удалить из дерева ключ xx. Если ключа xx в дереве нет, то ничего делать не надо;
  • exists xx — если ключ xx есть в дереве выведите «true», если нет «false»;
  • next xx — выведите минимальный элемент в дереве, строго больший xx, или «none» если такого нет;
  • prev xx — выведите максимальный элемент в дереве, строго меньший xx, или «none» если такого нет.

В дерево помещаются и извлекаются только целые числа, не превышающие по модулю 10910^9.

Выходные данные

Выведите последовательно результат выполнения всех операций exists, next, prev. Следуйте формату выходного файла из примера.

Пример

Входные данные

insert 2 insert 5 insert 3 exists 2 exists 4 next 4 prev 4 delete 5 next 4 prev 4

Выходные данные

true false 5 3 none 3

Решение

B. Сбалансированное двоичное дерево поиска

Ограничение по времени на тест: 2 секунды
Ограничение по памяти на тест: 512 мегабайт

Реализуйте сбалансированное двоичное дерево поиска.

Входные данные

Входной файл содержит описание операций с деревом, их количество не превышает 10510^5. В каждой строке находится одна из следующих операций:

  • insert xx — добавить в дерево ключ xx. Если ключ xx есть в дереве, то ничего делать не надо;
  • delete xx — удалить из дерева ключ xx. Если ключа xx в дереве нет, то ничего делать не надо;
  • exists xx — если ключ xx есть в дереве выведите «true», если нет «false»;
  • next xx — выведите минимальный элемент в дереве, строго больший xx, или «none» если такого нет;
  • prev xx — выведите максимальный элемент в дереве, строго меньший xx, или «none» если такого нет.

В дерево помещаются и извлекаются только целые числа, не превышающие по модулю 10910^9.

Выходные данные

Выведите последовательно результат выполнения всех операций exists, next, prev. Следуйте формату выходного файла из примера.

Пример

Входные данные

insert 2 insert 5 insert 3 exists 2 exists 4 next 4 prev 4 delete 5 next 4 prev 4

Выходные данные

true false 5 3 none 3

Решение

C. Добавление ключей

Ограничение по времени на тест: 2 секунды
Ограничение по памяти на тест: 256 мегабайт

Вы работаете в компании Макрохард и вас попросили реализовать структуру данных, которая будет хранить множество целых ключей.

Будем считать, что ключи хранятся в бесконечном массиве AA, проиндексированном с 11, исходно все его ячейки пусты. Структура данных должна поддерживать следующую операцию:

Insert(L,K)(L, K), где LL — позиция в массиве, а KK — некоторое положительное целое число.

Операция должна выполняться следующим образом:

  • Если ячейка A[L]A[L] пуста, присвоить A[L]KA[L] \gets K.
  • Если A[L]A[L] непуста, выполнить Insert(L+1,A[L])(L+1, A[L]) и затем присвоить A[L]KA[L] \gets K.

По заданным NN целым числам L1,L2,,LNL_1, L_2, \ldots, L_N выведите массив после выполнения последовательности операций:

Insert(L1,1)(L_1, 1) Insert(L2,2)(L_2, 2) \ldots Insert(LN,N)(L_N, N)

Входные данные

Первая строка входного файла содержит числа NN — количество операций Insert, которое следует выполнить и MM — максимальную позицию, которая используется в операциях Insert (1N131 072,1M131 072)(1 ⩽ N ⩽ 131\ 072, 1 ⩽ M ⩽ 131\ 072).

Следующая строка содержит NN целых чисел LiL_i, которые описывают операции Insert, которые следует выполнить (1LiM)(1 ⩽ L_i ⩽ M).

Выходные данные

Выведите содержимое массива после выполнения всех сделанных операций Insert. На первой строке выведите WW — номер максимальной непустой ячейки в массиве. Затем выведите WW целых чисел — A[1],A[2],,A[W]A[1], A[2], \ldots, A[W]. Выводите нули для пустых ячеек.

Пример

Входные данные

5 4 3 3 4 1 3

Выходные данные

6 4 0 5 2 3 1

Решение

D. И снова сумма

Ограничение по времени на тест: 5 секунд
Ограничение по памяти на тест: 256 мегабайт

Реализуйте структуру данных, которая поддерживает множество SS целых чисел, с котором разрешается производить следующие операции:

  • add(i)\operatorname{add}(i) — добавить в множество SS число ii (если он там уже есть, то множество не меняется);
  • sum(l,r)\operatorname{sum}(l, r) — вывести сумму всех элементов xx из SS, которые удовлетворяют неравенству lxrl ⩽ x ⩽ r.

Входные данные

Исходно множество SS пусто. Первая строка входного файла содержит nn — количество операций (1n300 000)(1 ⩽ n ⩽ 300\ 000). Следующие nn строк содержат операции. Каждая операция имеет вид либо «+ ii», либо «? ll rr». Операция «? ll rr» задает запрос sum(l,r)\operatorname{sum}(l, r).

Если операция «+ ii» идет во входном файле в начале или после другой операции «+», то она задает операцию add(i)\operatorname{add}(i). Если же она идет после запроса «?», и результат этого запроса был yy, то выполняется операция add((i+y)mod109)\operatorname{add}((i + y) \bmod 10^9).

Во всех запросах и операциях добавления параметры лежат в интервале от 00 до 10910^9.

Выходные данные

Для каждого запроса выведите одно число — ответ на запрос.

Пример

Входные данные

6 + 1 + 3 + 3 ? 2 4 + 1 ? 2 4

Выходные данные

3 7

Решение

KK-й максимум

Ограничение по времени на тест: 2 секунды
Ограничение по памяти на тест: 512 мегабайт

Напишите программу, реализующую структуру данных, позволяющую добавлять и удалять элементы, а также находить kk-й максимум.

Входные данные

Первая строка входного файла содержит натуральное число nn — количество команд (n100 000)(n ⩽ 100\ 000). Последующие nn строк содержат по одной команде каждая. Команда записывается в виде двух чисел cic_i и kik_i — тип и аргумент команды соответственно (ki109|k_i| ⩽ 10^9). Поддерживаемые команды:

  • 1: Добавить элемент с ключом kik_i.
  • 0: Найти и вывести kik_i-й максимум.
  • -1: Удалить элемент с ключом kik_i.

Гарантируется, что в процессе работы в структуре не требуется хранить элементы с равными ключами или удалять несуществующие элементы. Также гарантируется, что при запросе kik_i-го максимума, он существует.

Выходные данные

Для каждой команды нулевого типа в выходной файл должна быть выведена строка, содержащая единственное число — kik_i-й максимум.

Пример

Входные данные

11 1 5 1 3 1 7 0 1 0 2 0 3 -1 5 1 10 0 1 0 2 0 3

Выходные данные

7 5 3 10 7 3

Решение

F. Неявный ключ

Ограничение по времени на тест: 2 секунды
Ограничение по памяти на тест: 256 мегабайт

Научитесь быстро делать две операции с массивом:

  • add i x — добавить после ii-го элемента xx (0in)(0 ⩽ i ⩽ n)
  • del i — удалить ii-й элемент (1in)(1 ⩽ i ⩽ n)

Входные данные

На первой строке n0n_0 и mm (1n0,m105)(1 ⩽ n_0, m ⩽ 10^5) — длина исходного массива и количество запросов. На второй строке n0n_0 целых чисел от 00 до 109110^9 - 1 — исходный массив. Далее mm строк, содержащие запросы. Гарантируется, что запросы корректны: например, если просят удалить ii-й элемент, он точно есть.

Выходные данные

Выведите конечное состояние массива. На первой строке количество элементов, на второй строке сам массив.

Пример

Входные данные

3 4 1 2 3 del 3 add 0 9 add 3 8 del 2

Выходные данные

3 9 2 8

Решение

G. Переместить в начало

Ограничение по времени на тест: 6 секунд
Ограничение по памяти на тест: 512 мегабайт

Вам дан массив a1=1a_1 = 1, a2=2a_2 = 2, \ldots, an=na_n = n и последовательность операций: переместить элементы с lil_i по rir_i в начало массива. Например, для массива 2, 3, 6, 1, 5, 4, после операции (2, 4) новый порядок будет 3, 6, 1, 2, 5, 4. А после применения операции (3, 4) порядок элементов в массиве будет 1, 2, 3, 6, 5, 4.

Выведите порядок элементов в массиве после выполнения всех операций.

Входные данные

В первой строке входного файла указаны числа nn и mm (2n100 000,1m100 000)(2 ⩽ n ⩽ 100\ 000, 1 ⩽ m ⩽ 100\ 000) — число элементов в массиве и число операций. Следующие mm строк содержат операции в виде двух целых чисел: lil_i и rir_i (1lirin)(1 ⩽ l_i ⩽ r_i ⩽ n).

Выходные данные

Выведите nn целых чисел — порядок элементов в массиве после применения всех операций.

Пример

Входные данные

6 3 2 4 3 5 2 2

Выходные данные

1 4 5 2 3 6

Решение

H. Развороты

Ограничение по времени на тест: 1 секунда
Ограничение по памяти на тест: 512 мегабайт

Вам дан массив a1=1a_1 = 1, a2=2a_2 = 2, \ldots, an=na_n = n и последовательность операций: переставить элементы с lil_i по rir_i в обратном порядке. Например, для массива 1, 2, 3, 4, 5, после операции (2, 4) новый порядок будет 1, 4, 3, 2, 5. А после применения операции (3, 5) порядок элементов в массиве будет 1, 4, 5, 2, 3.

Выведите порядок элементов в массиве после выполнения всех операций.

Входные данные

В первой строке входного файла указаны числа nn и mm (2n100 000,1m100 000)(2 ⩽ n ⩽ 100\ 000, 1 ⩽ m ⩽ 100\ 000) — число элементов в массиве и число операций. Следующие mm строк содержат операции в виде двух целых чисел: lil_i и rir_i (1lirin)(1 ⩽ l_i ⩽ r_i ⩽ n).

Выходные данные

Выведите nn целых чисел — порядок элементов в массиве после применения всех операций.

Пример

Входные данные

5 3 2 4 3 5 2 2

Выходные данные

1 4 5 2 3

Решение

I. Эх, дороги

Ограничение по времени на тест: 2 секунды
Ограничение по памяти на тест: 256 мегабайт

В многострадальном Тридесятом государстве опять готовится дорожная реформа. Впрочем, надо признать, дороги в этом государстве находятся в довольно плачевном состоянии. Так что реформа не повредит. Одна проблема — дорожникам не развернуться, поскольку в стране действует жесткий закон — из каждого города должно вести не более двух дорог. Все дороги в государстве двусторонние, то есть по ним разрешено движение в обоих направлениях (разумеется, разметка отсутствует). В результате реформы некоторые дороги будут строиться, а некоторые другие закрываться на бессрочный ремонт.

Петя работает диспетчером в службе грузоперевозок на дальние расстояния. В связи с предстоящими реформами, ему необходимо оперативно определять оптимальные маршруты между городами в условиях постоянно меняющейся дорожной ситуации. В силу большого количества пробок и сотрудников дорожной полиции в городах, критерием оптимальности маршрута считается количество промежуточных городов, которые необходимо проехать.

Помогите Пете по заданной последовательности сообщений об изменении структуры дорог и запросам об оптимальном способе проезда из одного города в другой, оперативно отвечать на запросы.

Входные данные

В первой строке входного файла заданы числа nn — количество городов, mm — количество дорог в начале реформы и qq — количество сообщений об изменении дорожной структуры и запросов (1n,m100 000,q200 000)(1 ⩽ n, m ⩽ 100\ 000, q ⩽ 200\ 000). Следующие mm строк содержат по два целых числа каждая — пары городов, соединенных дорогами перед реформой. Следующие qq строк содержат по три элемента, разделенных пробелами. «+ ii jj» означает строительство дороги от города ii до города jj, «- ii jj» означает закрытие дороги от города ii до города jj, «? ii jj» означает запрос об оптимальном пути между городами ii и jj.

Гарантируется, что в начале и после каждого изменения никакие два города не соединены более чем одной дорогой, и из каждого города выходит не более двух дорог. Никакой город не соединяется дорогой сам с собой.

Выходные данные

На каждый запрос вида «? ii jj» выведите одно число — минимальное количество промежуточных городов на маршруте из города ii в город jj. Если проехать из ii в jj невозможно, выведите -1.

Пример

Входные данные

5 4 6 1 2 2 3 1 3 4 5 ? 1 2 ? 1 5 - 2 3 ? 2 3 + 2 4 ? 1 5

Выходные данные

0 -1 1 2